package inabit.inabitcompiler.productions.variable;

import inabit.compiler.parser.grammar.NonTerminal;
import inabit.compiler.parser.grammar.Production;
import inabit.compiler.parser.grammar.Symbol;
import inabit.compiler.parser.grammar.Terminal;
import inabit.data.Variable;
import inabit.impl.data.ContinuousVariable;
import inabit.impl.data.DiscreteVariable;
import inabit.impl.data.EnumeratedVariable;
import inabit.impl.data.GenericVariable;
import inabit.inabitcompiler.lexical.InabitTokenClass;
import inabit.inabitcompiler.parser.InabitSemanticAction;

import java.util.ArrayList;
import java.util.List;

/**V -> L D;*/
/**@author Rafael Rocha*/
public class V_Rule extends Production{
	private NonTerminal L;
	private NonTerminal D;
	
	public V_Rule() {
		super("V");
	}

	@Override
	protected Symbol[] production(final NonTerminal nonTerminal) {
		L = new NonTerminal("L");
		D = new NonTerminal("D");
		Symbol[] symbols ={
				L,
				D,
				new Terminal(InabitTokenClass.SEMI_COLON),
				new InabitSemanticAction(nonTerminal) {
					
					@Override
					public void execute() throws Exception {
						String[] varIds = L.code.split(",");
						if(D.code.isEmpty()) {//sem tipo
							for(String s : varIds) {
								if(getVariable(s) != null) {
									throw new Exception("Variable \'" + s + "\' was already declared");
								}
								addVariable(new GenericVariable(s));
							}
						}else {//com tipo
							String[] type = D.code.split(":");
							
							if(type[0].equals("continuous")) {
								String[] limits = type[1].split(",");
								for(String s : varIds){
									if(getVariable(s) != null) {
										throw new Exception("Variable \'" + s + "\' was already declared");
									}
									ContinuousVariable v = new ContinuousVariable(s,
											Double.parseDouble(limits[0]),
											Double.parseDouble(limits[1]));
									addVariable(v);
								}
							}else if(type[0].equals("discrete")){
								String[] limits = type[1].split(",");
								for(String s : varIds){
									if(getVariable(s) != null) {
										throw new Exception("Variable \'" + s + "\' was already declared");
									}
									DiscreteVariable v = new DiscreteVariable(s,
											Long.parseLong(limits[0]),
											Long.parseLong(limits[1]));
									addVariable(v);
								}
							}else if(type[0].equals("enum")){
								String[] params = type[1].split(",");
								for(String s : varIds) {
									if(getVariable(s) != null) {
										throw new Exception("Variable \'" + s + "\' was already declared");
									}
									EnumeratedVariable v = new EnumeratedVariable(s, params);
									addVariable(v);
								}
							}
						}
						
					}
				}
		};
		return symbols;
	}
}
